package com.wpf.system.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wpf.system.SystemApplication;
import com.wpf.system.common.response.ResultUtils;
import com.wpf.system.common.response.ResultVO;
import com.wpf.system.common.utils.RedisUtils;
import com.wpf.system.service.UserService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;

@RestController
@RequestMapping("/api/captcha")
public class CaptchaController {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private UserService userService;

    @Value("${spring.mail.username}")
    private String emailFrom;

    @PostMapping("/code")
    public void getNormalCode(HttpServletRequest request, HttpServletResponse response)throws IOException {
        response.setHeader("Cache-Control","no-store, no-cache");
        response.setContentType("image/jpeg");
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4,30 );
        String code = captcha.getCode();
        String ip = request.getRemoteAddr();
        String key = ip+code;
        redisUtils.set(key,code,60L);
        captcha.write(response.getOutputStream());
        response.getOutputStream().close();
    }

    @PostMapping("/mathCode")
    public void getMathCode(HttpServletRequest request, HttpServletResponse response)throws IOException {
        response.setHeader("Cache-Control","no-store, no-cache");
        response.setContentType("image/jpeg");
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4,5 );
        captcha.setGenerator(new MathGenerator());
        String code = captcha.getCode();
        int re ;
        int number1 = Convert.toInt(code.substring(0,2));
        int number2 = Convert.toInt(code.substring(3,5));
        switch (code.substring(2,3)) {
            case "+":
                re = number1 + number2;
                break;
            case "-":
                re = number1 - number2;
                break;
            case "*":
                re = number1 * number2;
                break;
            default:
                re = number1 / number2;
                break;
        }
        String resultCode = Convert.toStr(re);
        String ip = request.getRemoteAddr();
        String key = ip+resultCode;
        redisUtils.set(key,resultCode,60L);
        captcha.write(response.getOutputStream());
        response.getOutputStream().close();
    }

    @GetMapping("/checkMathCode")
    public ResultVO checkMathCode(HttpServletRequest request){
        String mathCode = request.getParameter("mathCode");
        if(StringUtils.isEmpty(mathCode)){
            return ResultUtils.error("验证结果不能为空!");
        }else {
            String ip = request.getRemoteAddr();
            String key = ip + mathCode;
            String rightCode = redisUtils.get(key);
            if (!mathCode.equals(rightCode)) {
                return ResultUtils.error("验证结果错误!");
            }
        }
        return ResultUtils.success("验证结果正确");
    }

    @GetMapping("/emailCode")
    public void sendEmailValid(HttpServletRequest request) throws IOException, TemplateException, MessagingException {
        //验证码
        int type = Convert.toInt(request.getParameter("sendType"));
        String randomCode = RandomUtil.randomNumbers(4);
        String ip = request.getRemoteAddr();
        String key = ip+type;
        redisUtils.set(key,randomCode,600L);

        // 配置 FreeMarker 模版位置
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
        // SystemApplication是启动类类名
        ClassLoader loader = SystemApplication.class.getClassLoader();
        configuration.setClassLoaderForTemplateLoading(loader, "templates");
        // 配置模版文件
        Template template = configuration.getTemplate("mailtemplate.ftl");
        // 渲染模版
        StringWriter mail = new StringWriter();

        HashMap<String, Object> map = new HashMap<>();
        String emailTitle = "";
        String emailAction = "";

        switch (type){
            case 5:
                emailTitle = "绑定邮箱";
                emailAction = "请忽略此邮件";
                break;
            case 4:
                emailTitle = "重置登录密码";
                emailAction = "你的登录密码可能已泄露，请立即更改登录密码";
                break;
            case 2:
                emailTitle = "重置支付密码";
                emailAction = "你的支付密码可能已泄露，为保障你的资金安全，请立即更改支付密码";
                break;
        }
        map.put("title",emailTitle);
        map.put("captcha", randomCode);
        map.put("action",emailAction);
        template.process(map, mail);

        // 构建一个邮件对象
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        // 设置邮件发送者
        helper.setFrom(emailFrom);
        // 设置邮件接收者
        helper.setTo(request.getParameter("mailAccount"));
        // 设置邮件的主题
        message.setSubject(emailTitle);
        // 设置邮件的正文
        helper.setText(mail.toString(), true);
        // 发送邮件
        javaMailSender.send(message);
    }

    @GetMapping("/checkEmailCode")
    public ResultVO checkEmailCode(HttpServletRequest request){
        String emailCode = request.getParameter("emailCode");
        int type = Convert.toInt(request.getParameter("sendType"));
        if(StringUtils.isEmpty(emailCode)){
            return ResultUtils.error("邮箱验证码不能为空!");
        }else {
            String ip = request.getRemoteAddr();
            String key = ip+type;
            String rightCode = redisUtils.get(key);
            if (!emailCode.equals(rightCode)) {
                return ResultUtils.error("邮箱验证码错误!");
            }
        }
        //验证码一致
        if(type==5){
            if(userService.editUserEmailStatus(Convert.toLong(request.getParameter("id")))){
                return ResultUtils.success("绑定邮箱成功！");
            }else{
                return ResultUtils.error("绑定邮箱失败！");
            }
        }else {
            return ResultUtils.success("邮箱验证码正确");
        }
    }
}
